package com.xian.im.modules.im.core.impl;

import cn.hutool.core.bean.BeanUtil;
import com.xian.im.common.constant.EhcacheConstant;
import com.xian.im.common.enums.UniqueTypeGenerateEnums;
import com.xian.im.common.model.dto.OrganizationDto;
import com.xian.im.common.model.from.OrganizationFrom;
import com.xian.im.common.sequence.UniqueSnowFlakeGenerate;
import com.xian.im.common.validator.ValidatorUtils;
import com.xian.im.common.validator.group.*;
import com.xian.im.modules.im.controller.model.login.OrgLoginReq;
import com.xian.im.modules.im.core.IOrganizationCoreService;
import com.xian.im.modules.im.entity.OrganizationEntity;
import com.xian.im.modules.im.service.OrganizationService;
import org.apache.commons.lang3.RandomStringUtils;
import org.apache.tomcat.util.security.MD5Encoder;
import org.springframework.beans.BeanUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.cache.annotation.CacheEvict;
import org.springframework.cache.annotation.Cacheable;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;

import java.util.Date;
import java.util.Objects;
import java.util.UUID;

/**
 * @program:
 * @description:
 * @author: liru.xian
 * @create: 2021-01-15 18:09
 **/
@Service
public class IOrganizationCoreServiceImpl implements IOrganizationCoreService {

    @Autowired
    private OrganizationService organizationService;
    @Autowired
    private UniqueSnowFlakeGenerate uniqueSnowFlakeGenerate;

    @Override
    @Transactional(rollbackFor = Exception.class)
    public OrganizationDto save(OrganizationFrom from) {
        ValidatorUtils.validateEntity(from, AddGroup.class);
        OrganizationEntity entity = new OrganizationEntity();
        OrganizationDto dto = new OrganizationDto();
        BeanUtils.copyProperties(from,entity);
        buildSecurity(entity);
        entity.setAccount(uniqueSnowFlakeGenerate.getSerialId(UniqueTypeGenerateEnums.xim_ORG.getCode()));
        entity.setCreateDate(new Date());
        organizationService.save(entity);
        BeanUtils.copyProperties(entity,dto);
        dto.setUniqueId(entity.getAccount());
        return dto;
    }

    @Override
    @Transactional(rollbackFor = Exception.class)
    @CacheEvict(cacheNames = EhcacheConstant.ORGANIZATION)
    public Boolean del(OrganizationFrom from) {
        ValidatorUtils.validateEntity(from, Group.class);
        organizationService.lambdaUpdate().eq(OrganizationEntity::getAccount,from.getUniqueId()).remove();
        return Boolean.TRUE;
    }

    @Override
    @Transactional(readOnly = true)
    @Cacheable(value = EhcacheConstant.ORGANIZATION)
    public OrganizationDto detail(Long id) {
        OrganizationDto dto = new OrganizationDto();
        OrganizationEntity entity = organizationService.getById(id);
        BeanUtils.copyProperties(entity,dto);
        dto.setUniqueId(entity.getAccount());
        return dto;
    }

    /**
     * 根据Ak 获取对象
     *
     * @param ak
     * @return
     */
    @Override
    @Transactional(readOnly = true)
    @Cacheable(value = EhcacheConstant.ORGANIZATION)
    public OrganizationDto findByAK(String ak) {
        return BeanUtil.copyProperties( organizationService.lambdaQuery().ge(OrganizationEntity::getAccessKey,ak).one(),OrganizationDto.class);
    }

    @Override
    public OrganizationDto getByUnique(String unique) {

        return BeanUtil.copyProperties( organizationService.lambdaQuery().ge(OrganizationEntity::getAccount,unique).one(),OrganizationDto.class);
    }

    /**
     * 检查租户是否有登录权限
     *
     * @param req
     * @return
     */
    @Override
    public Boolean checkLoginPermissions(OrgLoginReq req) {

        OrganizationEntity entity = organizationService.lambdaQuery().select(OrganizationEntity::getSalt,OrganizationEntity::getSecretKey).eq(OrganizationEntity::getAccessKey,req.getAccessKey()).one();
        if (entity != null) {
            String salt = entity.getSalt();
            String md5 = MD5Encoder.encode((req.getAccessKey() + salt).getBytes());
            if(Objects.equals(entity.getSecretKey(),md5)){
                return Boolean.TRUE;
            }
        }
        return Boolean.FALSE;
    }

    /**
     * @param from
     * @return
     */
    @Override
    public Integer ban(OrganizationFrom from) {
        ValidatorUtils.validateEntity(from, CheckGroup.class);
        OrganizationDto entity = getByUnique(from.getUniqueId());
        entity.setStatus(from.getStatus());
        organizationService.updateById(BeanUtil.copyProperties(entity,OrganizationEntity.class));
        return entity.getStatus();
    }


    /**
     * 计算密码
     * @param entity
     */
    private void  buildSecurity(OrganizationEntity entity){
        //sha256加密
        String salt = RandomStringUtils.randomAlphanumeric(20);
        entity.setSalt(salt);
        String key = UUID.randomUUID().toString().replace("-","").toLowerCase();
        entity.setAccessKey(key);
        entity.setSecretKey(MD5Encoder.encode((key+salt).getBytes()));
    }
}
